package com.ftw.commons.network

import android.content.Context
import android.text.TextUtils
import com.ftw.commons.R
import com.ftw.commons.bean.ApiException
import com.ftw.commons.bean.ApiSucc
import com.ftw.commons.widgets.CustomLoadingProgreeDialog
import com.google.gson.JsonParseException
import io.reactivex.Observer
import io.reactivex.disposables.Disposable
import org.greenrobot.eventbus.EventBus
import org.json.JSONException
import retrofit2.HttpException
import java.net.ConnectException
import java.net.SocketTimeoutException
import java.net.UnknownHostException
import java.text.ParseException

/**
 * 描    述：
 * 作    者：fantianwen
 * 时    间：2019/2/16  1:36 PM
 */

interface CallBack<in T> {

    fun onSuccess(t: T)

    fun onError(code: Int, msg: String)

}


open class HttpSubscriber<T>(
    private val mContext: Context,
    private var isShowDialog: Boolean = true,
    private var mCallBack: CallBack<T>
) : Observer<T> {


    constructor(context: Context, mCallBack: CallBack<T>) : this(context, true, mCallBack)

    companion object {

        /**
         * 对应HTTP的状态码
         */
        private const val BAD_REQUEST = 400
        private const val UNAUTHORIZED = 401
        private const val FORBIDDEN = 403
        private const val NOT_FOUND = 404
        private const val METHOD_NOT_ALLOWED = 405
        private const val REQUEST_TIMEOUT = 408
        private const val CONFLICT = 409
        private const val PRECONDITION_FAILED = 412
        private const val INTERNAL_SERVER_ERROR = 500
        private const val BAD_GATEWAY = 502
        private const val SERVICE_UNAVAILABLE = 503
        private const val GATEWAY_TIMEOUT = 504

        //数据解析异常
        const val CODE_MALFORMEDJSON = 1020

        //连接，或读取超时
        const val CODE_TIMEOUT = 1000

        //地址不可达
        const val VN_KNOW_ADDRESS = 1001

        //其它错误
        const val OTHER_EXCEPTION: Int = 1021

    }

    override fun onNext(t: T) {
        onAfter()
        mCallBack.onSuccess(t)
        EventBus.getDefault().post(ApiSucc())
    }

    override fun onComplete() {
        dismissDialog()
    }

    override fun onSubscribe(d: Disposable) {
        onBefore(mContext)
    }


    override fun onError(e: Throwable) {
        dismissDialog()
        var code: Int = OTHER_EXCEPTION
        var msg: String = mContext.getString(R.string.http_subscriber_connect_exception)
        when (e) {
            is HttpException -> {
                when (e.code()) {
                    BAD_REQUEST,
                    UNAUTHORIZED,
                    FORBIDDEN,
                    NOT_FOUND,
                    METHOD_NOT_ALLOWED,
                    REQUEST_TIMEOUT,
                    CONFLICT,
                    PRECONDITION_FAILED,
                    GATEWAY_TIMEOUT,
                    INTERNAL_SERVER_ERROR,
                    BAD_GATEWAY,
                    SERVICE_UNAVAILABLE -> {
                        code = e.code()
                        msg = mContext.getString(R.string.http_error, e.code())
                    }

                }
            }

            is JsonParseException,
            is JSONException,
            is ParseException -> {
                code = CODE_MALFORMEDJSON
                msg = mContext.getString(R.string.http_error_json_parse_error)
            }

            is ConnectException -> {
                code = CODE_TIMEOUT
                msg = mContext.getString(R.string.http_connection_error)
            }

            is UnknownHostException -> {
                code = VN_KNOW_ADDRESS
                msg = mContext.getString(R.string.http_subscriber_connect_exception)
            }

            is SocketTimeoutException -> {
                code = CODE_TIMEOUT
                msg = mContext.getString(R.string.http_socket_time_out)
            }

            is ApiException -> {
                code = e.code.toInt()
                msg = e.msg
//                when (e.code.toInt()) {
//                    //登录失效
//                    //你的账户已被删除，请联系管理员处理
//                    //您的账户已被禁用，请联系人管理员处理
//                }
            }

            else -> {
                when (TextUtils.isEmpty(e.message)) {
                    true -> {
                        code = OTHER_EXCEPTION
                        msg = mContext.getString(R.string.http_subscriber_no_know_exception)
                    }
                    else -> {
                        code = OTHER_EXCEPTION
                        msg = e.message!!
                    }
                }
            }
        }

        mCallBack.onError(code, msg)

        EventBus.getDefault().post(ApiException(code.toString(), msg))
    }

    private fun onBefore(context: Context) {
        showDialog(context)
    }

    private fun onAfter() {
        dismissDialog()
    }


    private var progressDialog: CustomLoadingProgreeDialog? = null

    private fun showDialog(context: Context) {

        if (null == progressDialog) {
            progressDialog = CustomLoadingProgreeDialog(context, R.style.CustomLoadingDialog)
        }

        progressDialog?.dismiss()
        progressDialog?.setCancelable(false)
        if (isShowDialog) {
            progressDialog?.show()
        }
    }

    private fun dismissDialog() {
        if (progressDialog!!.isShowing) {
            progressDialog?.dismiss()
        }

    }


}


